package org.erp.store.infrastructure.mq.listener;


import com.alibaba.fastjson2.JSONObject;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.erp.common.constant.RabbitmqConstant;
import org.erp.common.redis.service.RedisService;
import org.erp.store.infrastructure.constant.StoreRedisConstant;
import org.erp.store.infrastructure.convert.DeviceInventoryConvert;
import org.erp.store.domain.entity.DeviceInventory;

import org.erp.store.domain.dto.DeviceInventoryMqMessageDto;
import org.erp.store.service.DeviceInventoryService;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class DeviceInventoryMessageListener {

    @Resource
    private DeviceInventoryService deviceInventoryService;
    @Resource
    private DeviceInventoryConvert deviceInventoryConvert;

    @Resource
    private RedisService redisService;

    @RabbitListener(queues = RabbitmqConstant.ERP_STORE_UPDATE_QUEUE,
                     containerFactory = "rabbitListenerContainerFactory")
    public void handleDeviceInventoryUpdateMessage(Channel channel,
                                                   String message,
                                                   @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) throws Exception {
        log.info("收到更新MQ消息，内容：{}", message);
        DeviceInventoryMqMessageDto messageDto = JSONObject.parseObject(message, DeviceInventoryMqMessageDto.class);
        String lockKey = StoreRedisConstant.ERP_STORE_MQ_MESSAGE_UUID_KEY+messageDto.getUuid();
        try {
            Boolean first = redisService.setIfAbsent(lockKey, "1", 10, TimeUnit.MINUTES);
            if (Boolean.FALSE.equals(first)) {
                channel.basicAck(deliveryTag, false);
                log.warn("重复更新消息，已忽略，批次号：{}", messageDto.getUuid());
                return;
            }
            DeviceInventory deviceInventory = deviceInventoryConvert.messageToDeviceInventory(messageDto);
            boolean result = deviceInventoryService.updateById(deviceInventory);
            // 根据处理结果确认或拒绝消息
            if (result) {
                channel.basicAck(deliveryTag, false);
                log.info("设备库存更新处理成功，已确认消息");
            } else {
                channel.basicReject(deliveryTag, false);
                log.error("设备库存更新处理失败，拒绝消息");
            }

        } catch (Exception e) {
            log.error("设备库存更新处理异常，错误：{}", e.getMessage(), e);
            try { redisService.deleteObject(lockKey); } catch (Exception ignore) {}
            channel.basicReject(deliveryTag, false);
            throw e;
        }
    }
}
